package com.lzb.rock.base.facade;
/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.UpdateChainWrapper;

/**
 * 顶级 Service
 *
 * @author hubin
 * @since 2018-06-23
 */
public interface IService<T> {

	/**
	 * 插入一条记录（选择字段，策略插入）
	 *
	 * @param entity 实体对象
	 */
	Integer save(T entity);

	/**
	 * 根据 ID 删除
	 *
	 * @param id 主键ID
	 */
	Integer deleteById(Serializable id);

	/**
	 * 根据 columnMap 条件，删除记录
	 *
	 * @param columnMap 表字段 map 对象
	 */
	Integer deleteByMap(Map<String, Object> columnMap);

	/**
	 * 根据 entity 条件，删除记录
	 *
	 * @param queryWrapper 实体包装类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	Integer delete(Wrapper<T> queryWrapper);

	/**
	 * 根据 ID 选择修改
	 *
	 * @param entity 实体对象
	 */
	Integer updateById(T entity);

	/**
	 * 根据 whereEntity 条件，更新记录
	 *
	 * @param entity        实体对象
	 * @param updateWrapper 实体对象封装操作类
	 *                      {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
	 */
	Integer update(T entity, Wrapper<T> updateWrapper);

	/**
	 * 根据 UpdateWrapper 条件，更新记录 需要设置sqlset
	 *
	 * @param updateWrapper 实体对象封装操作类
	 *                      {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
	 */
	default Integer update(Wrapper<T> updateWrapper) {
		return update(null, updateWrapper);
	}

	/**
	 * 根据 ID 查询
	 *
	 * @param id 主键ID
	 */
	T getById(Serializable id);

	/**
	 * 查询（根据ID 批量查询）
	 *
	 * @param idList 主键ID列表
	 */
	Collection<T> listByIds(Collection<? extends Serializable> idList);

	/**
	 * 根据 Wrapper，查询一条记录 <br/>
	 * <p>
	 * 结果集，如果是多个会抛出异常，随机取一条加上限制条件 wrapper.last("LIMIT 1")
	 * </p>
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	default T getOne(Wrapper<T> queryWrapper) {
		return getOne(queryWrapper, true);
	}

	/**
	 * 根据 Wrapper，查询一条记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @param throwEx      有多个 result 是否抛出异常
	 */
	T getOne(Wrapper<T> queryWrapper, boolean throwEx);

	/**
	 * 根据 Wrapper，查询一条记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	Map<String, Object> getMap(Wrapper<T> queryWrapper);

	/**
	 * 根据 Wrapper，查询一条记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @param mapper       转换函数
	 */
	<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

	/**
	 * 根据 Wrapper 条件，查询总记录数
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	int count(Wrapper<T> queryWrapper);

	/**
	 * 查询总记录数
	 *
	 * @see Wrappers#emptyWrapper()
	 */
	default int count() {
		return count(Wrappers.emptyWrapper());
	}

	/**
	 * 查询列表
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	List<T> list(Wrapper<T> queryWrapper);

	/**
	 * 查询所有
	 *
	 * @see Wrappers#emptyWrapper()
	 */
	default List<T> list() {
		return list(Wrappers.emptyWrapper());
	}

	/**
	 * 翻页查询
	 *
	 * @param page         翻页对象
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	Page<T> page(Page<T> page, Wrapper<T> queryWrapper);

	/**
	 * 无条件翻页查询
	 *
	 * @param page 翻页对象
	 * @see Wrappers#emptyWrapper()
	 */
	default Page<T> page(Page<T> page) {
		return page(page, Wrappers.emptyWrapper());
	}

	/**
	 * 查询列表
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);

	/**
	 * 查询所有列表
	 *
	 * @see Wrappers#emptyWrapper()
	 */
	default List<Map<String, Object>> listMaps() {
		return listMaps(Wrappers.emptyWrapper());
	}

	/**
	 * 查询全部记录
	 */
	default List<Object> listObjs() {
		return listObjs(Function.identity());
	}

	/**
	 * 查询全部记录
	 *
	 * @param mapper 转换函数
	 */
	default <V> List<V> listObjs(Function<? super Object, V> mapper) {
		return listObjs(Wrappers.emptyWrapper(), mapper);
	}

	/**
	 * 根据 Wrapper 条件，查询全部记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	default List<Object> listObjs(Wrapper<T> queryWrapper) {
		return listObjs(queryWrapper, Function.identity());
	}

	/**
	 * 根据 Wrapper 条件，查询全部记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @param mapper       转换函数
	 */
	<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

	/**
	 * 翻页查询
	 *
	 * @param page         翻页对象
	 * @param queryWrapper 实体对象封装操作类
	 *                     {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	Page<Map<String, Object>> pageMaps(Page<T> page, Wrapper<T> queryWrapper);

	/**
	 * 无条件翻页查询
	 *
	 * @param page 翻页对象
	 * @see Wrappers#emptyWrapper()
	 */
	default Page<Map<String, Object>> pageMaps(Page<T> page) {
		return pageMaps(page, Wrappers.emptyWrapper());
	}

	/**
	 * 获取对应 entity 的 BaseMapper
	 *
	 * @return BaseMapper
	 */
	BaseMapper<T> getBaseMapper();

	/**
	 * 以下的方法使用介绍:
	 *
	 * 一. 名称介绍 1. 方法名带有 query 的为对数据的查询操作, 方法名带有 update 的为对数据的修改操作 2. 方法名带有 lambda
	 * 的为内部方法入参 column 支持函数式的
	 *
	 * 二. 支持介绍 1. 方法名带有 query 的支持以 {@link ChainQuery} 内部的方法名结尾进行数据查询操作 2. 方法名带有
	 * update 的支持以 {@link ChainUpdate} 内部的方法名为结尾进行数据修改操作
	 *
	 * 三. 使用示例,只用不带 lambda 的方法各展示一个例子,其他类推 1. 根据条件获取一条数据: `query().eq("column",
	 * value).one()` 2. 根据条件删除一条数据: `update().eq("column", value).delete()`
	 *
	 */

	/**
	 * 链式查询 普通
	 *
	 * @return QueryWrapper 的包装类
	 */
	default QueryChainWrapper<T> query() {
		return new QueryChainWrapper<>(getBaseMapper());
	}

	/**
	 * 链式查询 lambda 式
	 * <p>
	 * 注意：不支持 Kotlin
	 * </p>
	 *
	 * @return LambdaQueryWrapper 的包装类
	 */
	default LambdaQueryChainWrapper<T> lambdaQuery() {
		return new LambdaQueryChainWrapper<>(getBaseMapper());
	}

	/**
	 * 链式更改 普通
	 *
	 * @return UpdateWrapper 的包装类
	 */
	default UpdateChainWrapper<T> update() {
		return new UpdateChainWrapper<>(getBaseMapper());
	}

	/**
	 * 链式更改 lambda 式
	 * <p>
	 * 注意：不支持 Kotlin
	 * </p>
	 *
	 * @return LambdaUpdateWrapper 的包装类
	 */
	default LambdaUpdateChainWrapper<T> lambdaUpdate() {
		return new LambdaUpdateChainWrapper<>(getBaseMapper());
	}

}
